using cfg;
using System;
using GameUnityFramework.Resource;
using UnityEngine;
using UnityEngine.AddressableAssets;
using Object = UnityEngine.Object;

namespace GameLogics.Audio
{
    /// <summary>
    /// 新版音频管理器
    /// </summary>
    public class AudioManager : MonoBehaviour, IResourceLoader
    {
        public static AudioManager Instance;
        private AudioSource bgmSource;

        #region 音量设置

        /// <summary>
        /// 背景音乐音量
        /// </summary>
        private float bgmVolume = 1.0f;        //注意：该变量并非bgmSource当前音量，而是当前播放的bgm的配置音量
        public float BgmVolume
        {
            get
            {
                return bgmVolume;
            }
            set
            {
                bgmVolume = value;
                bgmSource.volume = value;
                MainLogic.GetLocalSetting().BGMVolume = value;
                MainLogic.SaveLocalSetting();
            }
        }

        /// <summary>
        /// 音乐是否为静音
        /// </summary>
        private bool muteBgm = false;
        public bool MuteBgm
        {
            get
            {
                return muteBgm;
            }
            set
            {
                muteBgm = value;
                bgmSource.mute = value;
                MainLogic.GetLocalSetting().MuteBGM = value;
                MainLogic.SaveLocalSetting();
            }
        }

        /// <summary>
        /// 音效音量
        /// </summary>
        private float sfxVolume = 1.0f;
        public float SfxVolume
        {
            get
            {
                return sfxVolume;
            }
            set
            {
                sfxVolume = value;
                MainLogic.GetLocalSetting().SFXVolume = value;
                MainLogic.SaveLocalSetting();
            }
        }

        /// <summary>
        /// 关闭音乐
        /// </summary>
        private bool muteSfx = false;
        public bool MuteSfx
        {
            get
            {
                return muteSfx;
            }
            set
            {
                muteSfx = value;
                MainLogic.GetLocalSetting().MuteSFX = value;
                MainLogic.SaveLocalSetting();
            }
        }

        #endregion

        private string curBgm;    //当前正在播放的背景音

        /// <summary>
        /// （回收内存用）当前正在播放的BGM
        /// </summary>
        private AudioClip _currentBgmClip;


        /// <summary>
        /// 启动音频管理器
        /// </summary>
        private void Awake()
        {
            if (Instance == null)
            {
                Instance = this;
                DontDestroyOnLoad(gameObject);
                Refresh();
            }
            else
            {
                Destroy(gameObject);
            }
        }

        /// <summary>
        /// 初始化
        /// </summary>
        private void Refresh()
        {
            if (bgmSource == null) bgmSource = gameObject.AddComponent<AudioSource>();
            var setting = MainLogic.GetLocalSetting();
            bgmVolume = setting.BGMVolume;
            muteBgm = setting.MuteBGM;
            sfxVolume = setting.SFXVolume;
            muteSfx = setting.MuteSFX;

            curBgm = string.Empty;
        }

        #region 音乐

        /// <summary>
        /// 打开Bgm
        /// </summary>
        public void OpenBgm()
        {
            MuteBgm = false;
        }

        /// <summary>
        /// 关闭Bgm
        /// </summary>
        public void CloseBgm()
        {
            MuteBgm = true;
        }


        /// <summary>
        /// 播放BGM
        /// isSwitch：传入的背景音和当前播放的一致，为false继续播放，为true从头开始播放
        /// </summary>
        public void PlayBgm(string bgmType)
        {
            if (bgmType == string.Empty) return;
            if (bgmType == curBgm) return;
            curBgm = bgmType;
            var bgmName = bgmType.ToString();
            LoadAudioClip(bgmName, (clip) =>
            {
                if (_currentBgmClip != null)
                {
                    _currentBgmClip.UnloadAudioData();
                    Addressables.Release(_currentBgmClip);
                    _currentBgmClip = null;
                }
                _currentBgmClip = clip;
                bgmSource.mute = MuteBgm;
                bgmSource.volume = BgmVolume;
                bgmSource.loop = true;
                bgmSource.clip = clip;
                bgmSource.Play();
            });
        }

        /// <summary>
        /// 停止BGM
        /// </summary>
        public void StopBGM()
        {
            bgmSource.clip = null;
            bgmSource.Stop();
        }
        #endregion

        #region 音效

        /// <summary>
        /// 打开音效
        /// </summary>
        public void OpenSound()
        {
            MuteSfx = false;
        }

        /// <summary>
        /// 关闭音效
        /// </summary>
        public void CloseSound()
        {
            MuteSfx = true;
        }


        /// <summary>
        /// 播放音效（按钮版）
        /// </summary>
        public void PlaySound(BtnSoundType soundType)
        {
            if (soundType == BtnSoundType.Null) return;
            PlaySound(soundType.ToString());
        }

        /// <summary>
        /// 播放音频
        /// </summary>
        private void PlaySound(string soundName)
        {
            if (MuteSfx) return;
            LoadAudioClip(soundName, (clip) =>
            {
                PlayClipAtPoint(clip, Vector3.zero, SfxVolume);
            });
        }
        #endregion

        #region 辅助方法

        /// <summary>
        ///   <para>Plays an AudioClip at a given position in world space.</para>
        /// </summary>
        /// <param name="clip">Audio data to play.</param>
        /// <param name="position">Position in world space from which sound originates.</param>
        /// <param name="volume">Playback volume.</param>
        public void PlayClipAtPoint(AudioClip clip, Vector3 position, [UnityEngine.Internal.DefaultValue("1.0F")] float volume)
        {
            GameObject gameObject = new GameObject("One shot audio");
            gameObject.transform.position = position;
            AudioSource audioSource = (AudioSource)gameObject.AddComponent(typeof(AudioSource));
            audioSource.clip = clip;
            audioSource.spatialBlend = 1f;
            audioSource.volume = volume;
            audioSource.Play();
            Object.Destroy((Object)gameObject, clip.length * ((double)Time.timeScale < 0.0099999997764825821 ? 0.01f : Time.timeScale));
        }

        /// <summary>
        /// 加载AudioClip
        /// </summary>
        private void LoadAudioClip(string name, Action<AudioClip> callback = null)
        {
            this.LoadAssetAsync<AudioClip>(name, (clip) =>
            {
                callback?.Invoke(clip);
            });
        }
        #endregion
    }
}